home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SAMLauncher.c
-
- Contains: Code for SAM Upgrader Plug-in
-
- Copyright: © 1997 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #include <Devices.h>
- #include <DriverGestalt.h>
- #include <SCSI.h>
- #include <Start.h>
- #include <Aliases.h>
- #include <Memory.h>
- #include <LowMem.h>
- #include <Quickdraw.h>
- #include <Files.h>
- #include <Resources.h>
- #include <TextUtils.h>
- #include <TextEdit.h>
- #include <MixedMode.h>
- #include <Events.h>
- #include <Processes.h>
- #include <Gestalt.h>
- #include <Printing.h>
- #include <assert.h>
- #include <StandardFile.h>
- #include <Types.h>
- #include <Folders.h>
-
- #include "SAMLauncher.h"
-
- // PROTOTYPES
-
- static Boolean HandleEventForPluginModule(EventRecord *inEvent);
- static void TerminatePluginModule(void);
- static ShellErr HandleMouseDownInSAMPanel(EventRecord *inEvent, Boolean *wasHandled);
- static Boolean HandleMouseDownInHelpPanel(EventRecord *inEvent);
- static OSErr SetupSAMPanel( SInt16 inPrefRsrcID );
- static OSErr SetupHelpPanel( SInt16 inPrefRsrcID );
- static void DisplayHelp(void);
- static void SetRadioButtonState(void);
- static void LaunchSAM( void );
- Boolean IsInstallableTarget ( SInt16 inVRefNum );
- VolWhereTypes WhereVol ( SInt16 vRefNum );
- Boolean IsCompactDisk ( SInt16 pDrRefNum, SInt16 pFSId );
- Boolean IsVolumeInvisible ( SInt16 pVRefNum );
- LockTypes VolLocked ( SInt16 vRefNum );
- short DriveNumToDriverRefNum ( short driveNum );
- short DriverNumberToDriveNumber ( SInt16 pDrRefNum );
- short PStrCmp ( ConstStr255Param p2, ConstStr255Param p1 );
- void VRefNumToVName ( SInt16 vRefNum, Str31 volName );
- void PStrSet ( Str255 destination, ConstStr255Param source );
-
- void AddVolumeToList ( short vRefNum, short count );
- unsigned short CountValidDrives ( void );
-
- // GLOBALS
- short gSysVolRefNum = -1;
- DialogPtr gSAMPanel = NULL,
- gHelpPanel = NULL;
- Boolean gHelpPanelOpen = false;
- RGBColor gBackGroundColor;
- RadioButtonStates gRadioButtonState;
- VolumeList gCurrentVolumeList[kMaxAttachedVolumes];
-
- static Boolean QuitProcess(ProcessSerialNumber *inApplicationPSN);
- static void SendQuitEventToApplication(void);
- static ShellErr SetUpAppleEventHandlers();
- static ShellErr RemoveAppleEventHandlers();
- pascal OSErr ChildDiedHandler(const AppleEvent *inAppleEvent, const AppleEvent */* outReply */, SInt32 /* inRefcon */ );
-
- // GLOBALS
-
- Boolean gApplicationLaunched = false;
- ProcessSerialNumber gApplicationPSN;
- AEEventHandlerUPP gChildDiedHandlerUPP = NULL;
- Boolean gQuitApponExit = true; //Set this to true if you want the application to quit when leaving the plugin.
- SInt16 gAppRefID = 0;
-
- //--------------------------------------------------------------------------------
- // InitializePluginModule
- //--------------------------------------------------------------------------------
-
- void InitializePluginModule(void* inPSTable, SInt32 inRefCon, Boolean inEnterAtBeginning)
- {
- #pragma unused (inEnterAtBeginning)
-
- ShellErr err;
- short refNum = -1;
- AuxWinHandle colorTableHdl;
- SInt32 info;
- Size actualSize;
- long foundDirID = 0;
-
- EnterPlugin();
- SetupPlugin(inPSTable);
-
- err = FindFolder( kOnSystemDisk, kSystemFolderType, kDontCreateFolder, &gSysVolRefNum, &foundDirID );
-
- // Register our event handler routine
- if ( err == noErr )
- err = PSRegisterHandler(kEventHandlerID, (UniversalProcPtr) HandleEventForPluginModule);
-
- if ( err == noErr )
- {
- // Resister our termination handler routine
- err = PSRegisterHandler(kTerminationHandlerID, (UniversalProcPtr) TerminatePluginModule);
-
- if ( err == noErr )
- {
- //Register ChildDied event handler
- err = SetUpAppleEventHandlers();
-
- if ( err == noErr )
- err = PSSetupNewPanel(kSAMPanelRsrcID, &gSAMPanel);
-
- if ( err == noErr )
- {
- err = SetupSAMPanel( LoWord( inRefCon) );
- if ( err == noErr )
- {
- PSGetGlobalData( kVirusPanelButtonState, ( GlobalDataPtr ) &gRadioButtonState, sizeof(RadioButtonStates), &actualSize );
-
- SetRadioButtonState();
- // Set content color to gray.
- if ( Gestalt( gestaltQuickdrawVersion, &info ) == noErr && info >= gestalt8BitQD && GetAuxWin( gSAMPanel, &colorTableHdl ) )
- {
- gBackGroundColor = ( *( *colorTableHdl )->awCTable )->ctTable[wContentColor].rgb;
- ( *( *colorTableHdl )->awCTable )->ctTable[wContentColor].rgb.red = 0xEEEE; // magnitude of red component
- ( *( *colorTableHdl )->awCTable )->ctTable[wContentColor].rgb.green = 0xEEEE; // magnitude of green component
- ( *( *colorTableHdl )->awCTable )->ctTable[wContentColor].rgb.blue = 0xEEEE; // magnitude of blue component
- RGBBackColor( &( *( *colorTableHdl )->awCTable )->ctTable[wContentColor].rgb );
- }
- PSShowPanel(gSAMPanel);
- }
- }
- }
- }
-
- if (err != noErr)
- {
- PSErrorAlert( err, true, "\p", "\p", "\p", "\p", kQuitButtonIndex, kContinueNotQuitBtnIndex );
- PSQuitShell(kDontAllowUserToContinue);
- }
- ExitPlugin();
- }
-
- //--------------------------------------------------------------------------------
- // TerminatePluginModule
- //--------------------------------------------------------------------------------
-
- static void TerminatePluginModule ()
- {
- AuxWinHandle colorTableHdl;
- SInt32 info;
-
- EnterPlugin();
-
- PSSetGlobalData( kVirusPanelButtonState, ( GlobalDataPtr ) &gRadioButtonState, sizeof(RadioButtonStates) );
- // Restore window content color to default.
- if ( Gestalt( gestaltQuickdrawVersion, &info ) == noErr && info >= gestalt8BitQD && GetAuxWin( gSAMPanel, &colorTableHdl ) )
- {
- ( *( *colorTableHdl )->awCTable )->ctTable[wContentColor].rgb = gBackGroundColor;
- RGBBackColor( &gBackGroundColor );
- }
-
- if (gQuitApponExit)
- {
- if (gApplicationLaunched)
- SendQuitEventToApplication();
- }
-
- RemoveAppleEventHandlers();
-
- ExitPlugin();
- }
-
- //--------------------------------------------------------------------------------
- // HandleEventForPluginModule
- //--------------------------------------------------------------------------------
-
- static Boolean HandleEventForPluginModule(EventRecord *inEvent)
- {
- ShellErr err;
- Boolean wasHandled = false;
-
- EnterPlugin();
-
- switch (inEvent->what)
- {
-
- case mouseDown:
- if(FrontWindow() == gSAMPanel)
- err = HandleMouseDownInSAMPanel(inEvent, &wasHandled);
- else if (FrontWindow() == gHelpPanel) // check for Help panel
- wasHandled = PSHandleHelpWindowEvent (gHelpPanel, inEvent);
- break;
-
- case osEvt: // Resume events only!
- if ( ( ( unsigned long ) inEvent->message >> 24 ) == suspendResumeMessage )
- {
- if ( ( inEvent->message & resumeFlag ) != 0 )
- ( void ) PSHandleHelpWindowEvent ( gHelpPanel, inEvent );
- }
- break;
- case kHighLevelEvent:
- AEProcessAppleEvent(inEvent);
-
- wasHandled = true;
- break;
- default:
- break;
- }
-
-
- ExitPlugin();
- return(wasHandled);
- }
-
- //--------------------------------------------------------------------------------
- // HandleMouseDownInSAMPanel
- //--------------------------------------------------------------------------------
- static ShellErr HandleMouseDownInSAMPanel(EventRecord *inEvent, Boolean *wasHandled)
- {
- short itemHit;
- ShellErr err = noErr;
-
- *wasHandled = false;
- if (PSGetPanelItemHit(gSAMPanel, inEvent, &itemHit))
- {
- switch (itemHit)
- {
- case kContinueButton:
- if ( gRadioButtonState != kDoNothing )
- {
- if ( gApplicationLaunched )
- { // If application has been launched
- err = SetFrontProcess(&gApplicationPSN);
- if ( err == noErr )
- *wasHandled = true;
- }
- else
- {
- LaunchSAM();
- *wasHandled = true;
- }
- }
- break;
-
- case kHelpButton:
- DisplayHelp();
- *wasHandled = true;
- break;
-
- case kScanForVirusesButton:
- gRadioButtonState = kScanForViruses;
- SetRadioButtonState();
- *wasHandled = true;
- break;
-
- case kRepairButton:
- gRadioButtonState = kRepair;
- SetRadioButtonState();
- *wasHandled = true;
- break;
-
- case kDoNothingButton:
- gRadioButtonState = kDoNothing;
- SetRadioButtonState();
- *wasHandled = true;
- break;
-
- default:
- break;
- }
- }
-
- return(err);
- }
-
- //--------------------------------------------------------------------------------
- // DisplayHelp
- //--------------------------------------------------------------------------------
-
- void DisplayHelp()
- {
- ShellErr err = noErr;
-
- if (gHelpPanelOpen) // Is it already open ?
- {
- err = PSShowPanel(gHelpPanel);
- }
- else
- {
- PSDisplayHelpWindow(gHelpPanel);
- gHelpPanelOpen = true;
- }
-
- if (err != noErr)
- {
- PSErrorAlert( err, true, "\p", "\p", "\p", "\p", kQuitButtonIndex, kContinueNotQuitBtnIndex );
- PSQuitShell(kDontAllowUserToContinue);
- }
- }
-
-
- //--------------------------------------------------------------------------------
- // SetupSAMPanel
- //
- // Sets up the various user items in the panel to their correct type, specifiying
- // the data found in the SAM preference resource which is read from the ClientData
- // file.
- // This routine should be called after PSSetupNewPanel() but before PSShowPanel() for
- // the SAM panel.
- //
- // Parameters
- //
- // Returns
- //--------------------------------------------------------------------------------
-
- static OSErr SetupSAMPanel( SInt16 inPrefRsrcID )
- {
- SAMPrefsHandle prefsHandle;
- SAMPrefsPtr prefsPtr;
- OSErr err = noErr;
-
-
- if( inPrefRsrcID == 0 )
- {
- SInt16** theIDHandle = (SInt16**) GetResource( 'paul', 128 ); // Get Resource ID for plugin preference
- if (theIDHandle != NULL)
- inPrefRsrcID = **theIDHandle;
- else
- inPrefRsrcID = 5000;
- }
-
-
- prefsHandle = (SAMPrefsHandle)GetResource(kSAMPrefsResType, inPrefRsrcID);
-
- if (prefsHandle != NULL)
- {
- if ((**prefsHandle).format == 0)
- {
- TEHandle text;
- short fontNum,
- fontStyle,
- fontSize;
- PanelItemType itemType;
- Handle itemHandle;
- Rect itemRect;
- PicHandle picHandle = NULL;
-
- HLock((Handle)prefsHandle);
- prefsPtr = *prefsHandle;
-
- gAppRefID = prefsPtr->SAMAppFileRefRsrsID;
-
- // Setup the panel title string.
- err = PSGetPanelItem(gSAMPanel, kTitleTextItem, &itemType, &itemHandle, &itemRect);
- if (err == noErr)
- {
- if (PSReadFontInfo(kFontInfoInShell, kUpgraderFonts, kLargeTextStyle, &fontNum, &fontStyle, &fontSize))
- {
- text = PSNewStyledStringItem(&itemRect, prefsPtr->SAMSTRListRsrsID, 1, fontNum, fontStyle, fontSize);
- if (text != NULL)
- err = PSSetPanelItem(gSAMPanel, kTitleTextItem, kStyledStringType, (Handle)text, &itemRect);
- else
- err = kCannotLoadNeededResourceErr;
- }
- }
- if (err == noErr)
- {
- // Setup the SAM panel main text.
- if (prefsPtr->mainTextReferenceID != 0) // Ignore id 0 if the Client does not want any text
- {
- err = PSGetPanelItem(gSAMPanel, kSAMPanelTextItem, &itemType, &itemHandle, &itemRect);
- if (err == noErr)
- {
- text = PSNewStyledTextItem(&itemRect, prefsPtr->mainTextReferenceID);
- if (text != NULL)
- err = PSSetPanelItem(gSAMPanel, kSAMPanelTextItem, kStyledTextType, (Handle)text, &itemRect);
- else
- err = kCannotLoadNeededResourceErr;
- }
- }
- }
- HUnlock((Handle)prefsHandle);
- }
- else
- {
- err = kUnsupportedPrefsFormatErr;
- }
- }
- else
- {
- err = kNoPrefsErr;
- }
-
- PSSetPanelItemAction(gSAMPanel, kContinueButton, kDefaultButtonMask);
- PSSetPanelItemAction(gSAMPanel, kContinueButton, kContinueButtonMask);
- PSSetPanelItemAction(gSAMPanel, kGoBackButton, kGoBackButtonMask);
-
- if (err == noErr)
- err = SetupHelpPanel( inPrefRsrcID );
-
- return(err);
- }
-
- //--------------------------------------------------------------------------------
- // SetupHelpPanel
- //
- // Sets up the various user items in the panel to their correct type, specifiying
- // the data found in the SAM preference resource which is read from the ClientData
- // file.
- // This routine should be called after PSSetupNewPanel() but before PSShowPanel() for
- // the Help panel.
- //
- // Parameters
- //
- // Returns
- //--------------------------------------------------------------------------------
-
- static OSErr SetupHelpPanel( SInt16 inPrefRsrcID )
- {
- SAMPrefsHandle prefsHandle;
- SAMPrefsPtr prefsPtr;
- OSErr err = noErr;
-
- prefsHandle = (SAMPrefsHandle)GetResource(kSAMPrefsResType, inPrefRsrcID);
-
- if (prefsHandle != NULL)
- {
- if ((**prefsHandle).format == 0)
- {
- Str255 helpPanelTitle;
-
- HLock((Handle)prefsHandle);
- prefsPtr = *prefsHandle;
-
- if ((prefsPtr->flags & kHelpTextInFile) == kHelpTextInFile)
- {
-
- GetIndString(helpPanelTitle, prefsPtr->SAMSTRListRsrsID, 2);
- err = PSSetupHelpWindow(kReadFromSimpleTextFile, prefsPtr->helpTextReferenceID,
- prefsPtr->baseHelpPICTResID, helpPanelTitle, &gHelpPanel );
- }
- else
- {
-
- GetIndString(helpPanelTitle, prefsPtr->SAMSTRListRsrsID, 2);
-
- err = PSSetupHelpWindow(kReadFromResourceFile, prefsPtr->helpTextReferenceID,
- prefsPtr->baseHelpPICTResID, helpPanelTitle, &gHelpPanel );
-
- }
-
-
- HUnlock((Handle)prefsHandle);
- }
- else
- {
- err = kUnsupportedPrefsFormatErr;
- }
- }
- else
- {
- err = kNoPrefsErr;
- }
-
- return(err);
- }
-
- //--------------------------------------------------------------------------------
- // SetRadioButtonState
- //
- // Parameters
- //
- // Returns
- //--------------------------------------------------------------------------------
- static void SetRadioButtonState( void )
- {
- PanelItemType itemType;
- Rect itemRect;
- Handle itemHandle;
-
- switch (gRadioButtonState)
- {
- case kScanForViruses:
- if( PSGetPanelItem( gSAMPanel, kScanForVirusesButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 1 );
- if( PSGetPanelItem( gSAMPanel, kRepairButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 0 );
- if( PSGetPanelItem( gSAMPanel, kDoNothingButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 0 );
- break;
-
- case kRepair:
- if( PSGetPanelItem( gSAMPanel, kScanForVirusesButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 0 );
- if( PSGetPanelItem( gSAMPanel, kRepairButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 1 );
- if( PSGetPanelItem( gSAMPanel, kDoNothingButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 0 );
- break;
-
- case kDoNothing:
- if( PSGetPanelItem( gSAMPanel, kScanForVirusesButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 0 );
- if( PSGetPanelItem( gSAMPanel, kRepairButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 0 );
- if( PSGetPanelItem( gSAMPanel, kDoNothingButton, &itemType, &itemHandle, &itemRect ) == noErr )
- SetControlValue( (ControlHandle)itemHandle, 1 );
- break;
-
- default:
- break;
- }
- }
-
- //--------------------------------------------------------------------------------
- // LaunchSAM
- //
- // Parameters
- //
- // Returns
- //--------------------------------------------------------------------------------
- static void LaunchSAM( void )
- {
- AppleEvent scanAppleEvent, returnAppleEvent;
- OSErr theErr = noErr;
- AEAddressDesc targetAddress;
- AEDescList fileList;
- short numberOfVolumes , i;
- AliasHandle volumeAlias;
- Boolean shouldRepair = false;
- FSSpec volFileSpec;
- PanelItemType itemType;
- Rect itemRect;
- Handle itemHandle;
-
-
- switch ( gRadioButtonState )
- {
- case kScanForViruses:
- case kRepair:
-
- numberOfVolumes = CountValidDrives();
-
- if ( PSLaunchFile( gAppRefID, 0, NULL, kLaunchAppInFront, &gApplicationPSN ) && numberOfVolumes > 0 )
- {
- gApplicationLaunched = true;
-
- // disable radio buttons -- so that if the user clicks back into the panel from Sam they'll be inactive
- if( PSGetPanelItem( gSAMPanel, kScanForVirusesButton, &itemType, &itemHandle, &itemRect ) == noErr)
- HiliteControl( (ControlHandle)itemHandle, 255 );
- if( PSGetPanelItem( gSAMPanel, kRepairButton, &itemType, &itemHandle, &itemRect ) == noErr)
- HiliteControl( (ControlHandle)itemHandle, 255 );
- if( PSGetPanelItem( gSAMPanel, kDoNothingButton, &itemType, &itemHandle, &itemRect ) == noErr)
- HiliteControl( (ControlHandle)itemHandle, 255 );
-
- theErr = AECreateList( NULL, 0, false, &fileList ); // create a list to add volume aliases to
-
- if( theErr == noErr )
- {
- for ( i = 1; i <= numberOfVolumes; i++ )
- {
- if( theErr == noErr )
- theErr = FSMakeFSSpec( gCurrentVolumeList[i].volRefNum, 1, (ConstStr255Param)gCurrentVolumeList[i].volName, &volFileSpec );
-
- if( theErr == noErr )
- theErr = NewAlias( NULL, &volFileSpec, &volumeAlias ); // add the alias to the list
-
- if( theErr == noErr )
- theErr = AEPutPtr( &fileList, 0, typeAlias, *volumeAlias, (**volumeAlias).aliasSize );
- }
- }
-
- if( theErr == noErr )
- theErr = AECreateDesc(typeProcessSerialNumber, &gApplicationPSN, sizeof(ProcessSerialNumber), &targetAddress );
-
- if( theErr == noErr )
- theErr = AECreateAppleEvent( 'AVEV', 'SCAN', &targetAddress, kAutoGenerateReturnID, kAnyTransactionID, &scanAppleEvent );
-
- if( theErr == noErr )
- theErr = AEPutParamDesc( &scanAppleEvent, keyDirectObject, &fileList ); // add the volume list to the apple event
-
- if( theErr == noErr && gRadioButtonState )
- theErr = AEPutParamPtr( &scanAppleEvent, 'REPR', typeBoolean, &shouldRepair, sizeof(Boolean) ); // add the repair parameter
-
- theErr = AESend( &scanAppleEvent, &returnAppleEvent, kAENoReply, kAEHighPriority, kNoTimeOut, NULL, NULL );
- }
-
- break;
-
- default:
- break;
- }
-
- }
-
-
-
- /*******************************************************************
- Function: CountValidDrives()
- Purpose: Counts the number of drives attached to the machine that
- can be installed onto and also build the list of said
- machines.
- Params: None
- Returns: The number of valid drives attached to the machine, or
- else zero (0), if there are no valid drives found
-
- Note: Fills gCurrentVolumeList with the current valid volumes
- for install which are attached to the machine
- *******************************************************************/
- unsigned short CountValidDrives ( void )
- {
- HParamBlockRec pb;
- short validVolCount = 0;
- ShellErr err = noErr;
-
- pb.volumeParam.ioNamePtr = NULL;
- pb.volumeParam.ioVolIndex = 1;
- pb.volumeParam.ioVDRefNum = 0;
- pb.ioParam.ioVRefNum = 0;
-
- do
- {
- err = PBHGetVInfoSync( &pb );
- if ( err == noErr && IsInstallableTarget( pb.volumeParam.ioVRefNum ) )
- AddVolumeToList( pb.ioParam.ioVRefNum, ++validVolCount );
-
- pb.volumeParam.ioVolIndex++;
- }while ( err == noErr );
-
- AddVolumeToList( NULL, validVolCount + 1 ); // put in a NULL in the vRefNum field to signify end of list
-
- return validVolCount;
- }
-
- /*******************************************************************
- Function: AddVolumeToList()
- Purpose: Adds a volume to the list of valid install volumes attached
- to the machine
- Params: (i) volume reference number of the volume to be added
- (ii) the number of volumes in the list
- Returns: None
- *******************************************************************/
- void AddVolumeToList ( short vRefNum, short count ) // <21>
- {
- Str255 theString = "\p";
-
- VRefNumToVName( vRefNum, theString );
-
- gCurrentVolumeList[count].volRefNum = vRefNum;
- PStrSet ( gCurrentVolumeList[count].volName, theString );
- }
-
-
- //--------------------------------------------------------------------------------
- // SendQuitEventToApplication
- //
- // Function that Quits gApplicationPSN
- //
- //--------------------------------------------------------------------------------
-
- void SendQuitEventToApplication()
- {
- OSErr theErr = noErr;
- AppleEvent theResultEvent;
-
-
- // Create target desc.
- AEDesc theTargetApp;
- theErr = AECreateDesc(typeProcessSerialNumber, &gApplicationPSN, sizeof(gApplicationPSN), &theTargetApp);
-
- // Bring them to the front in case they put up a modal dialog on quit (i.e. Save dialog).
- SetFrontProcess(&gApplicationPSN);
-
- // Create event
- if (theErr == noErr)
- {
- theErr = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theTargetApp, 0, 0, &theResultEvent);
- AEDisposeDesc(&theTargetApp);
- }
-
- // Send it
- if (theErr == noErr)
- {
- AppleEvent theReply;
- theReply.descriptorType = 'NULL';
- theReply.dataHandle = NULL;
-
- theErr = AESend(&theResultEvent, &theReply, kAENoReply, kAENormalPriority, 200, NULL, NULL);
-
- AEDisposeDesc(&theReply);
- AEDisposeDesc(&theResultEvent);
- }
- }
-
-
- //--------------------------------------------------------------------------------
- // SetUpAppleEventHandlers
- //--------------------------------------------------------------------------------
-
- ShellErr SetUpAppleEventHandlers()
- {
- ShellErr err = noErr;
- gChildDiedHandlerUPP = NewAEEventHandlerProc(ChildDiedHandler);
-
- // Any application
- err = AEInstallEventHandler(kCoreEventClass, kAEApplicationDied, gChildDiedHandlerUPP, kAEApplicationDied, false);
- if (err != noErr)
- err = kInternalErr;
-
- return(err);
- }
-
-
- //--------------------------------------------------------------------------------
- // RemoveAppleEventHandlers
- //--------------------------------------------------------------------------------
-
- ShellErr RemoveAppleEventHandlers()
- {
- ShellErr err = noErr;
-
- err = AERemoveEventHandler(kCoreEventClass, kAEApplicationDied, gChildDiedHandlerUPP, false);
- if (err != noErr)
- err = kInternalErr;
- else
- DisposeRoutineDescriptor(gChildDiedHandlerUPP);
-
- return(err);
- }
-
-
- //--------------------------------------------------------------------------------
- // ChildDiedHandler
- //--------------------------------------------------------------------------------
-
- pascal OSErr ChildDiedHandler(const AppleEvent *inAppleEvent, const AppleEvent * outReply , SInt32 inRefcon )
- {
- #pragma unused (outReply,inRefcon)
- SInt32 theActualSize;
- DescType returnedType;
- ProcessSerialNumber thelQuitApplicationPSN;
-
- EnterPlugin();
-
- AEGetParamPtr(inAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber, &returnedType, &thelQuitApplicationPSN, sizeof(gApplicationPSN), &theActualSize);
-
- // Check to make sure that the application that quit is the application that was launched
- if ((thelQuitApplicationPSN.highLongOfPSN == gApplicationPSN.highLongOfPSN) && (thelQuitApplicationPSN.lowLongOfPSN == gApplicationPSN.lowLongOfPSN))
- {
- gApplicationLaunched = false;
- PSGoToNextPlugin(kUseDefaultNextModuleName);
- }
-
- ExitPlugin();
-
- return noErr;
- }
-
-
-
-
- /*******************************************************************
- Function: IsInstallableTarget()
- Purpose: Checks to see if the volume can be installed on. A volume
- can be installed on if it is not invisible, if it is not locked
- and if it is "hard disk like"
- Params: (i) Volume reference number
- Returns: • True : The volume can be installed on
- • False : The volume cannot be installed on
- *******************************************************************/
- Boolean IsInstallableTarget ( SInt16 inVRefNum )
- {
- return inVRefNum != 0 && WhereVol(inVRefNum) == kHD && VolLocked(inVRefNum) == kUnlocked && !IsVolumeInvisible(inVRefNum);
- }
-
- /*******************************************************************
- Function: WhereVol()
- Purpose: Find out what type of volume we're dealing with
- Params: (i) Volume reference number
- Returns: One of { kHD, kFloppy1, kFloppy2, kFloppy3, kAppleShare, kRAMDisk, kTOPS, kAUXVolume, kCDROM, kUnknown }
- *******************************************************************/
- VolWhereTypes WhereVol ( SInt16 vRefNum )
- {
- Str255 diskName;
- HParamBlockRec pb;
- VolWhereTypes resultValue;
-
- if ( vRefNum == badVol )
- resultValue = kUnknown;
-
- else{
- pb.ioParam.ioNamePtr = ( StringPtr ) diskName;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.volumeParam.ioVolIndex = 0;
-
- if ( PBHGetVInfoSync( &pb ) == noErr ){
- // —— If the volume is offline then try to figure out what it is.
- if ( pb.volumeParam.ioVDrvInfo == offlineRefNum )
- {
- if ( pb.volumeParam.ioVDRefNum == floppy1DrvNum )
- resultValue = kFloppy1;
- else if ( pb.volumeParam.ioVDRefNum == floppy2DrvNum )
- resultValue = kFloppy2;
- else if ( pb.volumeParam.ioVDRefNum == floppy3DrvNum )
- resultValue = kFloppy3;
- else if ( IsCompactDisk( pb.volumeParam.ioVDRefNum, pb.volumeParam.ioVFSID ) ) // It's a CD-ROM disk.
- resultValue = kCDROM;
- else if ( pb.volumeParam.ioVFSID == kHFSFileManagerID ) // It's a normal HFS volume, assume it's some HD
- resultValue = kHD;
- else
- resultValue = kUnknown;
- }
-
- else
- { // —— If the volume is online then try to figure out what it is.
- if ( pb.volumeParam.ioVFSID == AppleShareFileManagerID ) // It's an AppleShare volume
- resultValue = kAppleShare;
- else if ( pb.volumeParam.ioVFSID == TOPSFileManagerID )
- resultValue = kTOPS;
- else if ( pb.volumeParam.ioVDRefNum == SONYRefNum && pb.volumeParam.ioVDrvInfo == floppy1DrvNum ) // It's a floppy
- resultValue = kFloppy1;
- else if ( pb.volumeParam.ioVDRefNum == SONYRefNum && pb.volumeParam.ioVDrvInfo == floppy2DrvNum ) // It's a floppy
- resultValue = kFloppy2;
- else if ( pb.volumeParam.ioVDRefNum == SONYRefNum && pb.volumeParam.ioVDrvInfo == floppy3DrvNum ) // It's a floppy
- resultValue = kFloppy3;
- else if ( pb.volumeParam.ioVDRefNum == oldHDRefNum ) // It's an old HD 20
- resultValue = kHD;
- else if ( IsCompactDisk(pb.volumeParam.ioVDRefNum, pb.volumeParam.ioVFSID ) ) // It's a CD-ROM disk
- resultValue = kCDROM;
- else if ( pb.volumeParam.ioVFSID == kHFSFileManagerID ) // It's a normal HFS volume, assume it's some HD
- resultValue = kHD;
- else
- resultValue = kUnknown;
- }
- }
- else
- resultValue = kUnknown;
- }
-
- return resultValue;
- }
-
-
- /*******************************************************************
- Function: IsCompactDisk()
- Purpose: Check to see if the volume is a CD
- Params: (i) Drive reference number
- (ii) File Spec ID
- Returns: • True : The volume is a CD
- • False : The volume is not a CD
- *******************************************************************/
- Boolean IsCompactDisk ( SInt16 pDrRefNum, SInt16 pFSId )
- {
- Boolean result = false;
- DCtlHandle theDctl;
- StringPtr thePtr, appleCDStr = "\p.AppleCD";
- DriverGestaltParam pb;
- OSErr status;
- short driverNumber, driveNumber;
- long sysVersion;
-
- // First check to see if it happens to be one of the drivers we know of.
- if ( ( pFSId == kHighSierraFileManagerID ) || ( pFSId == kISO9660FileManagerID ) || ( pFSId == kAudioCDFileManagerID ) )
- {
- result = true;
- }
- else
- {
- // If pDrRefNum is actually a drive number because the volume is ejected
- // then get its driver ref num.
- if ( pDrRefNum > 0 ){
- driverNumber = DriveNumToDriverRefNum( pDrRefNum );
- driveNumber = pDrRefNum;
- }
- else
- {
- driverNumber = pDrRefNum;
- driveNumber = DriverNumberToDriveNumber( pDrRefNum );
- }
-
- if ( Gestalt( gestaltSystemVersion, &sysVersion ) == noErr && sysVersion >= 0x0753 )
- {
- // use the DriverGestalt stuff introduced with PowerSurge machines
- pb.csCode = kDriverGestaltCode; // Setup Driver Gestalt PB
- pb.driverGestaltSelector = kdgDeviceType; // ask for Device Type
- pb.ioCRefNum = driverNumber; // Get the driver refNum
- pb.ioVRefNum = driveNumber; // Get the drive refNum
-
- status = PBStatusSync( ( ParmBlkPtr ) &pb ); // Do a Driver Gestalt call
-
- if ( ( status == noErr ) && ( pb.driverGestaltResponse == kdgCDType ) )
- result = true; // Device type is 'cdrm'
- }
- else
- {
- // use the old method
- theDctl = GetDCtlEntry( pDrRefNum );
- if ( theDctl != NULL )
- {
- if ( ( *theDctl )->dCtlFlags & 0x0040 )
- thePtr = ( StringPtr ) *( ( Handle ) ( ( *theDctl )->dCtlDriver ) );
- else
- thePtr = ( StringPtr ) ( ( *theDctl )->dCtlDriver );
-
- thePtr = ( StringPtr ) ( thePtr + 18 );
-
- if ( PStrCmp( thePtr, appleCDStr ) == 0 )
- result = true;
- }
- }
- }
-
- return result;
-
- }
-
- /*******************************************************************
- Function: IsVolumeInvisible()
- Purpose: Check to see if the volume is invisible
- Params: (i) Volume reference number
- Returns: • True : The volume is invisible
- • False : The volume is not invisible
- *******************************************************************/
- Boolean IsVolumeInvisible ( SInt16 pVRefNum )
- {
- #if GENERATINGPOWERPC
- #pragma options align=mac68k
- #endif
-
- typedef struct{
- Handle localHand; // handle to local info cache
- SInt16 version; // $0001 for first version
- SInt16 altPrivModel; // ***to be defined
- SInt32 attrib; // attribute bits for this volume
- SInt32 serverAdr; // network address of the server
- SInt32 volumeSpeed; // rating of volume speed in milliseconds
-
- // where do we get these?
- SInt32 minimalBufferSize; // buffer size to use which show reasonable feedback
- SInt32 optimalBufferSize; // buffer size of diminishing return
- } MetaInfo;
-
- #if GENERATINGPOWERPC
- #pragma options align=reset
- #endif
-
- CInfoPBRec volCatInfoPB;
- HParamBlockRec volInfoPB, volParmsPB;
- OSErr theErr, gestaltErr;
- SInt32 FSTVers;
- MetaInfo meta;
- Boolean isInvisible = false;
-
- volCatInfoPB.hFileInfo.ioNamePtr = NULL;
- volCatInfoPB.hFileInfo.ioVRefNum = pVRefNum;
- volCatInfoPB.hFileInfo.ioFDirIndex = -1;
- volCatInfoPB.hFileInfo.ioDirID = 0;
-
- theErr = PBGetCatInfoSync( &volCatInfoPB );
-
- if ( theErr == noErr ){
- isInvisible = ( volCatInfoPB.hFileInfo.ioFlFndrInfo.fdFlags & fInvisible ) == fInvisible;
-
- if ( isInvisible )
- {
- // check #1, HS or ISO with wold FST?
- volInfoPB.volumeParam.ioNamePtr = NULL;
- volInfoPB.volumeParam.ioVRefNum = pVRefNum;
- volInfoPB.volumeParam.ioVolIndex = 0;
- theErr = PBHGetVInfoSync( &volParmsPB );
-
- if ( ( theErr == noErr ) && ( ( volInfoPB.volumeParam.ioVFSID == 0x4242 ) || ( volInfoPB.volumeParam.ioVFSID == 0x4147 ) ) )
- {
- gestaltErr = Gestalt( 'hscd', &FSTVers );
- if ( ( gestaltErr != noErr ) || ( FSTVers < 0x0203 ) )
- { // if gestaltErr != noErr, then we're running an older FST that does not register Gestalt
- isInvisible = false;
- }
- }
-
- // check #2, boot volume?
- if ( gSysVolRefNum == pVRefNum )
- isInvisible = false;
-
- // check #3, appleshare volume?
- volParmsPB.ioParam.ioNamePtr = NULL;
- volParmsPB.ioParam.ioVRefNum = pVRefNum;
- volParmsPB.ioParam.ioReqCount = sizeof(MetaInfo);
- volParmsPB.ioParam.ioBuffer = ( Ptr ) &meta;
- if ( ( PBHGetVolParmsSync( &volParmsPB ) == noErr ) && ( meta.serverAdr != 0 ) )
- isInvisible = false;
- }
- }
-
- return isInvisible;
- }
-
- /*******************************************************************
- Function: VolLocked()
- Purpose: Check to see if the volume is locked
- Params: (i) Volume reference number
- Returns: One of { Unlocked, Hardware locked, Software locked }
- *******************************************************************/
- LockTypes VolLocked ( SInt16 vRefNum )
- {
- HParamBlockRec pb;
- LockTypes value_VolLocked;
-
- pb.ioParam.ioNamePtr = NULL;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.volumeParam.ioVolIndex = 0;
-
- if ( PBHGetVInfoSync( &pb ) != noErr )
- // Although there is an error here, we'll say it's unlocked because we want a better error to be determined by another routine later.
- value_VolLocked = kUnlocked;
- else if ( BTst(pb.volumeParam.ioVAtrb, 7 ) )
- value_VolLocked = kHWLock;
- else if ( BTst( pb.volumeParam.ioVAtrb, 15 ) )
- value_VolLocked = kSWLock;
- else
- value_VolLocked = kUnlocked;
-
- return value_VolLocked;
- }
-
- /*******************************************************************
- Function: DriveNumToDriverRefNum()
- Purpose: Given the drive number, get the driver reference number
- from the drive queue
- Params: (i) drive number
- Returns: Success : driver reference number
- Failure: 0 i( no drive queue element available )
- *******************************************************************/
- short DriveNumToDriverRefNum ( short driveNum )
- {
- DrvQElPtr drvQElem;
-
- // find the drive queue element
- drvQElem = ( DrvQElPtr ) ( GetDrvQHdr()->qHead );
- while ( ( drvQElem != NULL ) && ( drvQElem->dQDrive != driveNum ) )
- drvQElem = ( DrvQElPtr ) ( drvQElem->qLink );
-
- if ( drvQElem != NULL )
- return drvQElem->dQRefNum;
- else
- return 0;
- }
-
- /*******************************************************************
- Function: DriverNumberToDriveNumber()
- Purpose: Given the driver reference number, get the associated drive number
- Params: (i) driver reference number
- Returns: Success : drive number
- Failure: 0 i( no drive queue element available )
- *******************************************************************/
- short DriverNumberToDriveNumber ( SInt16 pDrRefNum )
- {
- DrvQElPtr drvQElem;
-
- drvQElem = (DrvQElPtr) (GetDrvQHdr()->qHead);
-
- while ((drvQElem != NULL ) && (drvQElem->dQRefNum != pDrRefNum))
- drvQElem = (DrvQElPtr) (drvQElem->qLink);
-
- if (drvQElem != NULL)
- return drvQElem->dQDrive;
- else
- return 0;
-
- }
-
- /*******************************************************************
- Function: VRefNumToVName()
- Purpose: Converts the volume reference number to its name
- Params: (i) Volume reference number
- (ii) Volume name (returned)
- Returns: None
- *******************************************************************/
- void VRefNumToVName ( SInt16 vRefNum, Str31 volName )
- {
- ParamBlockRec pb;
-
- volName[0] = 0;
- pb.ioParam.ioNamePtr = ( StringPtr ) volName;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.volumeParam.ioVolIndex = -1;
-
- PBGetVInfoSync( &pb );
- }
-
-
- /*******************************************************************
- Function: PStrCmp()
- Purpose: compare one pascal string with another (p1 == p2 ?)
- Params: (i) first pascal string to compare
- (ii) second pascal string to compare
- Returns: p1 == p2 : 0
- p1 > p2 : < 0
- p1 < p2 : > 0
- *******************************************************************/
- short PStrCmp ( ConstStr255Param p2, ConstStr255Param p1 )
- {
- short i, len;
-
- if ( ( unsigned char ) *p2 == ( unsigned char ) *p1 )
- {
- len = ( unsigned char ) *p2;
- for ( i=1; *p2 == *p1; p2++, p1++, i++ )
- if ( i > len )
- return 0;
-
- return ( ( unsigned char ) *p2 - ( unsigned char ) *p1 );
- }
- else
- return ( ( unsigned char ) *p2 - ( unsigned char ) *p1 );
- }
-
-
- /*******************************************************************
- Function: PStrSet()
- Purpose: assign one pascal string to another (destination = source)
- Params: (i) destination pascal string
- (ii) source pascal string
- Returns: none
- *******************************************************************/
- void PStrSet ( Str255 destination, ConstStr255Param source )
- {
- BlockMove( source, destination, *source + 1 );
- }
-